package cn.com.dcsgo.service.impl;

import cn.com.dcsgo.ProductFeignClient;
import cn.com.dcsgo.enums.ActivityType;
import cn.com.dcsgo.mapper.ActivityInfoMapper;
import cn.com.dcsgo.mapper.ActivityRuleMapper;
import cn.com.dcsgo.mapper.ActivitySkuMapper;
import cn.com.dcsgo.model.activity.ActivityInfo;
import cn.com.dcsgo.model.activity.ActivityRule;
import cn.com.dcsgo.model.activity.ActivitySku;
import cn.com.dcsgo.model.activity.CouponInfo;
import cn.com.dcsgo.model.order.CartInfo;
import cn.com.dcsgo.model.product.SkuInfo;
import cn.com.dcsgo.service.ActivityInfoService;
import cn.com.dcsgo.service.ActivityRuleService;
import cn.com.dcsgo.service.ActivitySkuService;
import cn.com.dcsgo.service.CouponInfoService;
import cn.com.dcsgo.vo.activity.ActivityRuleVo;
import cn.com.dcsgo.vo.order.OrderConfirmVo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 活动表 服务实现类
 * </p>
 *
 * @author Dcsgo
 * @since 2025-04-19
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class ActivityInfoServiceImpl extends ServiceImpl<ActivityInfoMapper, ActivityInfo> implements ActivityInfoService {
    private final ActivityRuleMapper activityRuleMapper;
    private final ActivitySkuMapper activitySkuMapper;
    private final ProductFeignClient productFeignClient;
    private final CouponInfoService couponInfoService;
    private final ActivitySkuService activitySkuService;
    private final ActivityRuleService activityRuleService;

    @Override
    public IPage<ActivityInfo> getPage(Page<ActivityInfo> pageParam) {
        Page<ActivityInfo> activityInfoPage = baseMapper.selectPage(pageParam, null);
        //活动类型使用 activityTypeString 返回给前端，需要手动转换一下
        List<ActivityInfo> activityInfoList = activityInfoPage.getRecords();
        activityInfoList.forEach(
                activityInfo -> activityInfo.setActivityTypeString(activityInfo.getActivityType().getComment())
        );
        return activityInfoPage;
    }

    @Override
    public Map<String, Object> findActivityRuleList(Long id) {
        Map<String, Object> result = new HashMap<>();
        //获取营销活动关联的规则列表
        List<ActivityRule> activityRuleList = activityRuleMapper.selectList(
                new LambdaQueryWrapper<ActivityRule>().eq(ActivityRule::getActivityId, id)
        );
        //获取营销活动规则关联的skuId集合
        List<ActivitySku> activitySkuList = activitySkuMapper.selectList(
                new LambdaQueryWrapper<ActivitySku>().eq(ActivitySku::getActivityId, id)
        );
        List<SkuInfo> skuInfoList = new ArrayList<>(0);
        //获取规则关联的sku信息列表
        if (!activitySkuList.isEmpty()) {
            List<Long> skuIds = activitySkuList.stream().map(ActivitySku::getSkuId).collect(Collectors.toList());
            skuInfoList = productFeignClient.getSkuInfoByIds(skuIds);
        }
        //封装结果
        result.put("activityRuleList", activityRuleList);
        result.put("skuInfoList", skuInfoList);
        return result;
    }

    @Override
    public void saveActivityRule(ActivityRuleVo activityRuleVo) {
        //先将当前活动关联的规则数据都删除掉-rule、sku
        activityRuleMapper.delete(
                new LambdaQueryWrapper<ActivityRule>().eq(ActivityRule::getActivityId, activityRuleVo.getActivityId())
        );
        activitySkuMapper.delete(
                new LambdaQueryWrapper<ActivitySku>().eq(ActivitySku::getActivityId, activityRuleVo.getActivityId())
        );

        //添加新的规则
        for (ActivityRule activityRule : activityRuleVo.getActivityRuleList()) {
            //设置前端未设置值的属性
            //设置规则关联到的活动id
            activityRule.setActivityId(activityRule.getActivityId());
            //设置规则活动类型
            activityRule.setActivityType(activityRule.getActivityType());
            activityRuleMapper.insert(activityRule);
        }
        for (ActivitySku activitySku : activityRuleVo.getActivitySkuList()) {
            activitySku.setActivityId(activityRuleVo.getActivityId());
            activitySkuMapper.insert(activitySku);
        }
    }

    @Override
    public List<SkuInfo> findSkuInfoBySkuName(String keyword) {
        // 获取模糊查询得到的 sku list
        List<SkuInfo> skuInfoList = productFeignClient.getSkuInfoByName(keyword);
        // 根据skuInfoList查询其中处于活动中（有与之关联的其它促销活动）的 sku id list
        ArrayList<SkuInfo> notExistSkuInfoList = new ArrayList<>(0);
        // 模糊查询为空不用再作排除了
        log.debug("skuInfoList:{}", skuInfoList);
        if (!skuInfoList.isEmpty()) {
            List<Long> skuInfoListIds = skuInfoList.stream().map(SkuInfo::getId).collect(Collectors.toList());
            List<Long> existSkuIds = baseMapper.selectExistBySkuIds(skuInfoListIds);
            log.debug("existSkuIds:{}", existSkuIds);
            notExistSkuInfoList = new ArrayList<>(skuInfoList.size() - existSkuIds.size());
            for (SkuInfo skuInfo : skuInfoList) {
                if (!existSkuIds.contains(skuInfo.getId())) {
                    notExistSkuInfoList.add(skuInfo);
                }
            }
        }
        return notExistSkuInfoList;
    }

    @Override
    public Map<Long, List<String>> getActivitySimpleInfoBySkuIds(List<Long> ids) {
        Map<Long, List<String>> result = new HashMap<>();
        ids.forEach(skuId -> {
            List<ActivityRule> activityRuleList = baseMapper.findActivityRuleListBySkuId(skuId);
            if (!CollectionUtils.isEmpty(activityRuleList)) {
                List<String> activityRuleSampleInfo = new ArrayList<>();
                activityRuleList.forEach(activityRule -> activityRuleSampleInfo.add(getRuleDesc(activityRule)));
                result.put(skuId, activityRuleSampleInfo);
            }
        });
        return result;
    }

    @Override
    public Map<String, Object> getActivityAndCouponInfo(Long skuId, Long userId) {
        Map<String, Object> result = new HashMap<>();
        // 获取sku关联的促销活动信息
        List<ActivityRule> activityRuleList = baseMapper.findActivityRuleListBySkuId(skuId);
        for (ActivityRule activityRule : activityRuleList) {
            activityRule.setRuleDesc(this.getRuleDesc(activityRule));
        }
        result.put("activityRuleList", activityRuleList);
        // 获取与skuId、userId关联的优惠券信息
        List<CouponInfo> couponInfoList = couponInfoService.findCouponRuleList(skuId, userId);
        result.put("couponInfoList", couponInfoList);
        return result;
    }

    @Override
    public OrderConfirmVo getCartSettlementInformation(Long userId, List<CartInfo> items) {
        // 获取购物车中商品关联的活动id集合
        List<ActivitySku> activitySkuList = activitySkuService.getList(items);
        // 将商品关联的促销活动集合分组成：Map<ActivityId,Set<SkuId>> 一个sku只能关联一个活动故用 set 进行存储
        Map<Long, Set<Long>> activitySkuMap = activitySkuList.stream().collect(Collectors.groupingBy(
                ActivitySku::getActivityId,
                Collectors.mapping(ActivitySku::getSkuId, Collectors.toSet())
        ));
        // 获取商品关联的促销活动规则
        List<ActivityRule> activityRuleList = activityRuleService.getList(activitySkuList);
        // 同样按照活动id进行分组 Map<ActivityId,List<ActivityRule>>
        Map<Long, List<ActivityRule>> activityRuleMap = new HashMap<>(0);
        if (!CollectionUtils.isEmpty(activityRuleList)) {
            activityRuleMap = activityRuleList.stream().collect(
                    Collectors.groupingBy(ActivityRule::getActivityId));
        }

        return null;
    }

    /**
     * 获取简略的规则信息
     *
     * @param activityRule 活动规则
     * @return 简略的规则信息
     */
    private String getRuleDesc(ActivityRule activityRule) {
        ActivityType activityType = activityRule.getActivityType();
        StringBuilder ruleDesc = new StringBuilder();
        if (activityType == ActivityType.FULL_REDUCTION) {
            ruleDesc
                    .append("满")
                    .append(activityRule.getConditionAmount())
                    .append("元减")
                    .append(activityRule.getBenefitAmount())
                    .append("元");
        } else {
            // 优惠折扣(类似0.88 0.5)转换为整数
            BigDecimal benefitDiscount = activityRule.getBenefitDiscount();
            int benefitDiscountInt = 10;
            // 检查是否有小数部分
            if (benefitDiscount.scale() > 0) {
                // 获取小数部分
                BigDecimal fractionalPart = benefitDiscount.subtract(benefitDiscount.setScale(0, RoundingMode.DOWN));
                log.debug("小数部分:{}", fractionalPart);
                benefitDiscountInt = benefitDiscount.multiply(new BigDecimal("100")).intValue();
                // 最后一位位0表示 是类似0.5的折扣 100乘多了
                benefitDiscountInt = benefitDiscountInt % 10 == 0 ? benefitDiscountInt / 10 : benefitDiscountInt;
            } else {
                log.error("activityRule.getBenefitDiscount().scale() <= 0 折扣数没有小数部分");
            }
            ruleDesc
                    .append("满")
                    .append(activityRule.getConditionNum())
                    .append("打")
                    .append(benefitDiscountInt)
                    .append("折");
        }
        return ruleDesc.toString();
    }

}
